package com.nineclock.document.service.impl;



import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.nineclock.common.entity.PageResult;
import com.nineclock.common.enums.ResponseEnum;
import com.nineclock.common.exception.NcException;
import com.nineclock.common.threadlocal.CurrentUserHolder;
import com.nineclock.common.utils.BeanHelper;
import com.nineclock.common.utils.CountUtil;
import com.nineclock.document.dto.DocFileDto;
import com.nineclock.document.dto.DocFileHistoryDto;
import com.nineclock.document.dto.DocFolderDto;
import com.nineclock.document.dto.DocumentDto;
import com.nineclock.document.mapper.DocCollaborationsMapper;
import com.nineclock.document.mapper.DocFileHistoryMapper;
import com.nineclock.document.mapper.DocFileMapper;
import com.nineclock.document.mapper.DocFolderMapper;
import com.nineclock.document.pojo.DocCollaborations;
import com.nineclock.document.pojo.DocFile;
import com.nineclock.document.pojo.DocFileHistory;
import com.nineclock.document.pojo.DocFolder;
import com.nineclock.document.service.DocService;
import com.nineclock.system.dto.SysCompanyUserDTO;
import com.nineclock.system.feign.SysUserFeign;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
@SuppressWarnings("all")
public class DocServiceImpl implements DocService {

    @Autowired
    DocFileMapper docFileMapper;

    @Autowired
    DocFileHistoryMapper docFileHistoryMapper;

    @Autowired
    DocFolderMapper docFolderMapper;

    @Autowired
    private DocCollaborationsMapper docCollaborationsMapper;

    @Autowired
    private SysUserFeign sysUserFeign;


    @Override
    public List<DocFileHistoryDto> queryDocFileHistory(Integer fileId) {


        if (fileId == null){
            throw new NcException(ResponseEnum.FILE_NOT_FOUND);
        }
        LambdaQueryWrapper<DocFileHistory> lambdaQW = new LambdaQueryWrapper<>();
        lambdaQW.eq(DocFileHistory::getFileId,fileId);
        List<DocFileHistory> docFileHistories = docFileHistoryMapper.selectList(lambdaQW);
        String username = CurrentUserHolder.get().getUsername();

        List<DocFileHistoryDto> dtos = BeanHelper.copyWithCollection(docFileHistories, DocFileHistoryDto.class);

        for (DocFileHistoryDto dto : dtos) {
            dto.setUserName(username);
        }
        return dtos;

    }

    @Override
    public void insertFile(DocFileDto docFileDto) {
        if (docFileDto==null){
            throw new  NcException(ResponseEnum.INVALID_USERNAME_PASSWORD);
        }

        DocFile docFile = BeanHelper.copyProperties(docFileDto, DocFile.class);
        docFile.setCompanyId(CurrentUserHolder.get().getCompanyId());
        docFile.setCreateUserId(CurrentUserHolder.get().getCompanyUserId());
        docFile.setCreateTime(new Date());
        docFile.setUpdateUserId(CurrentUserHolder.get().getCompanyUserId());
        //设置文件大小
        byte[] bytes = docFileDto.getContent().getBytes();
        //计算输入文本的大小
        String size = CountUtil.getSize(bytes.length);
        docFile.setFileSize(size);


        docFileMapper.insert(docFile);

        DocFileHistory docFileHistory = BeanHelper.copyProperties(docFileDto, DocFileHistory.class);

        docFileHistory.setOperateTime(new Date());
        docFileHistory.setOperateUserId(docFile.getCompanyId());
        docFileHistory.setFileId(docFile.getId());
        docFileHistory.setFileName(docFile.getName());

        docFileHistoryMapper.insert(docFileHistory);


    }

    @Override
    public void insertFolder(DocFolderDto docFolderDto) {
        if (docFolderDto==null || docFolderDto.getName()==null){
            throw new NcException(ResponseEnum.INVALID_USERNAME_PASSWORD);
        }


        DocFolder docFolder = BeanHelper.copyProperties(docFolderDto, DocFolder.class);

        docFolder.setCreateTime(new Date());

        docFolder.setCompanyId(CurrentUserHolder.get().getCompanyId());
        docFolder.setCreateUserId(CurrentUserHolder.get().getCompanyUserId());
        docFolderMapper.insert(docFolder);
    }

    @Override
    public PageResult<DocFileDto> queryDocByPage(String keyword,Long page,Long pageSize) {


        if (page == null || pageSize == null){

            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }


        Page<DocFile> docFilePage = new Page<>(page,pageSize);

        LambdaQueryWrapper<DocFile> wrapper = new LambdaQueryWrapper<>();

        wrapper.eq(DocFile::getCompanyId, CurrentUserHolder.get().getCompanyId());

        if (StrUtil.isNotEmpty(keyword)){

            wrapper.like(DocFile::getName,keyword);
        }

        docFilePage = docFileMapper.selectPage(docFilePage, wrapper);

        List<DocFile> docFiles = docFilePage.getRecords();

        if (CollectionUtil.isEmpty(docFiles)){

            return null;

        }

        List<DocFileDto> docFileDtos = BeanHelper.copyWithCollection(docFiles, DocFileDto.class);



        for (DocFileDto docFileDto : docFileDtos) {

            Long createUserId = docFileDto.getCreateUserId();

            SysCompanyUserDTO companyUserDTO = sysUserFeign.queryCompanyUserById(createUserId).getData();

            docFileDto.setCreator(companyUserDTO);

            Long id = docFileDto.getId();

            LambdaQueryWrapper<DocCollaborations> wrapper1 = new LambdaQueryWrapper<>();

            wrapper1.eq(DocCollaborations::getFileId,id);

            List<DocCollaborations> docCollaborations = docCollaborationsMapper.selectList(wrapper1);

            List<SysCompanyUserDTO> sysCompanyUserDTOList = new ArrayList<>();

            for (DocCollaborations docCollaboration : docCollaborations) {

                Long collaborationId = docCollaboration.getCollaborationId();
                SysCompanyUserDTO sysCompanyUserDTO = sysUserFeign.queryCompanyUserById(collaborationId).getData();

                sysCompanyUserDTOList.add(sysCompanyUserDTO);
            }

            docFileDto.setCollaborations(sysCompanyUserDTOList);


        }

        PageResult<DocFileDto> pageResult = new PageResult<>();

        pageResult.setRows(docFileDtos);

        pageResult.setTotal(docFilePage.getTotal());

        pageResult.setTotalPage(docFilePage.getPages());

        return pageResult;
    }

    @Override
    public void UpdateStatus(Long fileId, Short status) {

        if (fileId == null || status == null){

            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }

        DocFile docFile = docFileMapper.selectById(fileId);

        if (docFile == null){

            throw new NcException(ResponseEnum.FILE_NOT_FOUND);
        }

        docFile.setStatus(status);

        docFileMapper.updateById(docFile);
    }

    @Override
    public DocumentDto queryDocument(Long parentFoldId, String keyword) {

        //参数判断
        if (parentFoldId == null) {
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }

        //查询父文件夹下的子文件夹
        LambdaQueryWrapper<DocFolder> folderQW = new LambdaQueryWrapper<>();

        folderQW.eq(DocFolder::getCompanyId, CurrentUserHolder.get().getCompanyId());//当前公司的文件夹
        folderQW.eq(DocFolder::getParentId, parentFoldId);//父文件夹id
        folderQW.eq(DocFolder::getStatus, 1);//文件夹可用

        List<DocFolder> folderList = docFolderMapper.selectList(folderQW);

        //类型转换
        List<DocFolderDto> folderDtoList = BeanHelper.copyWithCollection(folderList, DocFolderDto.class);

        //查询文件
        LambdaQueryWrapper<DocFile> fileQW = new LambdaQueryWrapper<>();

        fileQW.eq(DocFile::getCompanyId, CurrentUserHolder.get().getCompanyId());//当前公司的文件
        fileQW.eq(DocFile::getFolderId, parentFoldId);//归属的文件夹ID
        fileQW.eq(DocFile::getStatus,1);//可用

        //查询当前员工协作的文件
        LambdaQueryWrapper<DocCollaborations> docCollaborationsQW = new LambdaQueryWrapper<>();

        docCollaborationsQW.eq(DocCollaborations::getCollaborationId,CurrentUserHolder.get().getCompanyUserId());

        List<DocCollaborations> collaborationsList = docCollaborationsMapper.selectList(docCollaborationsQW);

        List<Long> fileIds = collaborationsList.stream().map(collaborations -> {
            return collaborations.getFileId();
        }).collect(Collectors.toList());

        fileQW.and(wrapper -> {
            wrapper.eq(DocFile::getCreateUserId,CurrentUserHolder.get().getCompanyUserId())//当前员工id
                    .or().in(DocFile::getId,fileIds)//协作文件的id
                    .or().in(DocFile::getPermission,0,1);//公共
        });

        List<DocFile> fileList = docFileMapper.selectList(fileQW);

        List<DocFileDto> fileDtoList = BeanHelper.copyWithCollection(fileList, DocFileDto.class);

        for (DocFileDto docFileDto : fileDtoList) {
            //其他属性赋值
            //作者
            List<Long> companyUserIds = new ArrayList<>();

            companyUserIds.add(docFileDto.getCreateUserId());

            List<SysCompanyUserDTO> companyUserDTOList = sysUserFeign.getCompanyUserByIds(companyUserIds).getData();

            SysCompanyUserDTO companyUserDTO = companyUserDTOList.get(0);

            docFileDto.setCreator(companyUserDTO);

            //文件协作者集合
            LambdaQueryWrapper<DocCollaborations> wrapper = new LambdaQueryWrapper<>();

            wrapper.eq(DocCollaborations::getFileId,docFileDto.getId());

            List<DocCollaborations> docCollaborationsList = docCollaborationsMapper.selectList(wrapper);

            List<Long> userIds = docCollaborationsList.stream().map(docCollaborations -> {
                return docCollaborations.getCollaborationId();
            }).collect(Collectors.toList());

            docFileDto.setCollaborations(sysUserFeign.getCompanyUserByIds(userIds).getData());

            //用户名
            docFileDto.setUserName(companyUserDTO.getUserName());

            //最后更新人名称
            Long updateUserId = docFileDto.getUpdateUserId();

            List<SysCompanyUserDTO> userDTOS = sysUserFeign.getCompanyUserByIds(Arrays.asList(updateUserId)).getData();

            docFileDto.setUpdateUserName(userDTOS.get(0).getUserName());
        }

        return new DocumentDto(folderDtoList, fileDtoList);
    }

}

